part of "../group.dart";

/// "组"的本质实际上是Map，每个入口下都是一个单独的List
/// 它的G就是"分类依据"，比如按出生年月、性别分类
/// 而List<T>就是这个分类下的所有数据，由于数据一般不止一条，因此用List管理
///
/// 比如说，3班有50个学生，其中“3班”就是一种G，而“50个学生”就是List<T>
/// 又比如说，全国的新生儿如果用日期来统计，就会在每个日期上都有一个List，包含了当天出生的所有婴儿Object
typedef Group<G, T> = Map<G, List<T>>;

extension SortGroup<G, T> on Iterable<T> {
  /// 通过某种分组方法[sortMethod]，将List转化为采用[G]分类的[Group]
  /// 比如说，给定一组婴儿，可以按出生年份将它们归类，也可以按照性别归类
  Group<G, T> toGruop<G>(G Function(T) sortMethod) {
    // 创建一个空的Map
    final Group<G, T> map = {};

    // 对于List中的每一项，将归类到Map中
    for (T item in this) {
      G group = sortMethod(item);

      // 如果还不存在，则创建一个空的List
      if (!map.containsKey(group)) map[group] = [];
      map[group]!.add(item);
    }

    // 返回map
    return map;
  }
}

extension MergeGroups<G, T> on Group<G, T> {
  /// 比如一个医院有一个[Group]表格，统计了不同日期出生的每一个婴儿
  /// 当另一家医院也有这样的表格时，就可以调用这个方法一起统计合并两家的表格
  void merge(Group<G, T> other) {
    other.forEach((key, value) {
      if (containsKey(key)) {
        this[key]!.addAll(value);
      } else {
        this[key] = value;
      }
    });
  }
}
